﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

namespace NF_Tools
{
    public class StatusControl : Button, IContainerControl
    {
        private string _desc = "空闲中";
        [Category("NanQi"), Description("描述")]
        public string Desc
        {
            get { return _desc; }
            set { _desc = value; }
        }

        private int _count = 0;
        [Category("NanQi"), Description("数量")]
        public int Count
        {
            get { return _count; }
            set 
            {
                if (_count != value)
                    this.Invalidate();
                _count = value;
                
            }
        }
        [Category("NanQi"), Description("边框颜色")]
        public Color BorderColor
        {
            get { return _borderColor; }
            set { _borderColor = value; }
        }

        #region field
        private Control _activeControl;

        private float _countFontSize = 24;
        private Font _countFont = null;

        private float _descFontSize = 16;
        private Font _descFont = null;

        private bool _isHovered = false;
        private bool _isPressed = false;
        private bool _isFocused = false;

        private Point _mouseLocation = Point.Empty;

        private int _borderWidth = 4;
        private Color _borderColor = Color.FromArgb(176, 176, 176);

        private Timer _timer;
        private int _startAngle = 271;
        private int _sweepAngle = 10;
        private int speed = 0;
        private int odd = 1;

        #endregion

        public StatusControl()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.OptimizedDoubleBuffer |
                    ControlStyles.ResizeRedraw |
                    ControlStyles.UserPaint, true);

            this.Width = 70;
            this.Height = 70;

            _borderColor = BorderColor;
            
            _countFont = new Font("Segoe UI", _countFontSize, FontStyle.Bold, GraphicsUnit.Pixel);
            _descFont = new Font("Segoe UI", _descFontSize, FontStyle.Regular, GraphicsUnit.Pixel);

            _timer = new Timer();
            _timer.Interval = 30;
            _timer.Tick += new EventHandler(_timer_Tick);

            this.SizeChanged += new EventHandler(Status_SizeChanged);
        }

        void _timer_Tick(object sender, EventArgs e)
        {
            _startAngle += speed;
            if (_startAngle > 360)
            {
                _startAngle = 0;
            }

            odd++;

            if ((_startAngle > 270 || _startAngle <= 90) && (odd & 3) == 0)
            {
                speed++;
            }
            else if (_startAngle > 90 && _startAngle <= 270 && (odd & 3) == 0)
            {
                speed--;
            }

            Invalidate();
        }

        void Status_SizeChanged(object sender, EventArgs e)
        {
            if (this.Width < 70)
            {
                this.Width = 70;
            }

            this.Height = this.Width;

            var zoom = (this.Width - 70) / 7;

            _countFont = new Font("Segoe UI", _countFontSize + zoom, FontStyle.Bold, GraphicsUnit.Pixel);
            _descFont = new Font("Segoe UI", _descFontSize + zoom, FontStyle.Regular, GraphicsUnit.Pixel);
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            var g = pevent.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            g.Clear(this.Parent.BackColor);

            var offset_border = _borderWidth / 2;
            //_borderColor = _isFocused ? SystemColors.Highlight : Color.FromArgb(176, 176, 176);

            var offset = _isPressed ? 2 : 1;

            using (var pen = new Pen(_borderColor, _borderWidth))
            {
                g.DrawEllipse(pen, offset_border, offset_border,
                    this.Width - _borderWidth - offset, this.Height - _borderWidth - offset);
            }

            if (_isFocused)
            {
                using (var pen = new Pen(Color.White, _borderWidth))
                {
                    g.DrawArc(pen, offset_border, offset_border,
                        this.Width - _borderWidth - offset,
                        this.Height - _borderWidth - offset, _startAngle, _sweepAngle);
                }
            }

            var descTextSize = TextRenderer.MeasureText(_desc, _descFont);
            var marginTop = _borderWidth * 3;
            TextRenderer.DrawText(g, _desc, _descFont,
                new Point((this.Width - descTextSize.Width) / 2 + _borderWidth / 2, 
                    marginTop + (this.Width - 70) / 7),
                Color.FromArgb(90, 90, 90));

            var countTextSize = TextRenderer.MeasureText(_count.ToString(), _countFont);
            marginTop += descTextSize.Height - 3;
            TextRenderer.DrawText(g, _count.ToString(), _countFont,
                new Point((this.Width - countTextSize.Width) / 2 + _borderWidth / 2,
                    marginTop + (this.Width - 70) / 7),
                Color.FromArgb(90, 90, 90));
        }

        #region Focus Methods

        protected override void OnGotFocus(EventArgs e)
        {
            _isFocused = true;
            _timer.Start();
            Invalidate();

            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            _isFocused = false;
            _isHovered = false;
            _isPressed = false;
            _timer.Stop();
            Invalidate();

            base.OnLostFocus(e);
        }

        protected override void OnEnter(EventArgs e)
        {
            _isFocused = true;
            _timer.Start();
            Invalidate();

            base.OnEnter(e);
        }

        protected override void OnLeave(EventArgs e)
        {
            _isFocused = false;
            _isHovered = false;
            _isPressed = false;
            _timer.Stop();
            Invalidate();

            base.OnLeave(e);
        }

        #endregion

        #region IContainerControl 成员

        public bool ActivateControl(Control active)
        {
            if (Controls.Contains(active))
            {
                active.Select();
                _activeControl = active;

                return true;
            }

            return false;
        }

        public Control ActiveControl
        {
            get { return _activeControl; }
            set { _activeControl = value; }
        }

        #endregion

        #region Keyboard Methods

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
            {
                _isHovered = true;
                _mouseLocation = Point.Empty;
                _isPressed = true;
                Invalidate();
            }

            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            _isHovered = false;
            _isPressed = false;
            Invalidate();

            base.OnKeyUp(e);
        }

        #endregion

        #region Mouse Methods

        protected override void OnMouseEnter(EventArgs e)
        {
            _isHovered = true;
            Invalidate();

            base.OnMouseEnter(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _mouseLocation = e.Location;
                _isPressed = true;
                Invalidate();
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            _isPressed = false;
            Invalidate();

            base.OnMouseUp(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            _isHovered = false;
            Invalidate();

            base.OnMouseLeave(e);
        }

        #endregion
    }
}
